package com.demo.commons.utils;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Tools {
    //数组扩容-int   如果使用了泛型就不能定义成静态类

    /**
     * @param a   数组
     * @param num 扩容数量
     * @return
     */
    public static int[] arraysInt(int[] a, int num) {
        if (a != null) {
            int[] n = new int[a.length + num];
            for (int i = 0; i < a.length; i++) {
                n[i] = a[i];
            }
            return n;
        } else {
            return a;
        }
    }

    //数组扩容-byte
    public static byte[] arraysByte(byte[] a, int num) {
        if (a != null) {
            byte[] n = new byte[a.length + num];
            for (int i = 0; i < a.length; i++) {
                n[i] = a[i];
            }
            return n;
        } else {
            return a;
        }
    }

    //数组扩容-char
    public static char[] arraysChar(char[] a, int num) {
        if (a != null) {
            char[] n = new char[a.length + num];
            for (int i = 0; i < a.length; i++) {
                n[i] = a[i];
            }
            return n;
        } else {
            return a;
        }
    }

    //数组扩容-float
    public static float[] arraysByet(float[] a, int num) {
        if (a != null) {
            float[] n = new float[a.length + num];
            for (int i = 0; i < a.length; i++) {
                n[i] = a[i];
            }
            return n;
        } else {
            return a;
        }
    }

    /**
     * 字符转换  byte   string
     * random整数  math.ramdom小数
     * int f = Integer.parseInt( "011a",2 );2进制字符串转换为十进制不是数字报错推荐使用
     * Integer.valueOf( "12a" );比上面多一次操作
     **/
    public static byte[] inString(String str) {
        byte[] bytes = new byte[]{};
        if (str != null) {
            bytes = str.getBytes();
        }
        return bytes;
    }

    //获取时间date日期
    public static String getDate() {
        Date nowDay = new Date();
        //第一种  年  月 日 时 分 秒 星期
        String q = String.format("%tY", nowDay);
        String w = String.format("%tm", nowDay);
        String e = String.format("%td", nowDay);
        String r = String.format("%tH", nowDay);
        String t = String.format("%tM", nowDay);
        String y = String.format("%tS", nowDay);
        String u = String.format("%tA", nowDay);
        String str = q + "年" + w + "月" + e + "日" + r + ":" + t + ":" + y + ":" + u;
        //第二种 时间转字符串
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(nowDay);
        //字符串转时间
        String time1 = "2018-9-05";
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyy-mm-dd");
        try {
            Date parse = simpleDateFormat1.parse(time1);
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        return str;
    }

    //时间日历
    public static String getCalendar() {
        Calendar cal = Calendar.getInstance();
        int a = cal.get(Calendar.YEAR);
        int b = cal.get(Calendar.MONTH + 1);
        int c = cal.get(Calendar.DAY_OF_MONTH);
        int d = cal.get(Calendar.HOUR_OF_DAY);
        int e = cal.get(Calendar.MINUTE);
        int f = cal.get(Calendar.SECOND);
        int g = cal.get(Calendar.DAY_OF_WEEK) - 1;
        String str = a + "年" + b + "月" + c + "日" + d + ":" + e + ":" + f + ":" + g;
        //自定义时间
        Calendar cal1 = Calendar.getInstance();
        cal1.set(2018, 9, 1, 12, 2, 2);
        Date time = cal1.getTime();
        return str;
    }

    //数字加减法  BigDecimal(12)里面是数字自动保留无限位数 必须改为字符串
    //使用内部类
    class Anonymity {
        BigDecimal bd;
        BigDecimal bd1;

        //加法
        public String add(String aVal, String bVal) {
            bd = new BigDecimal(aVal);
            bd1 = new BigDecimal(bVal);
            BigDecimal add = bd.add(bd1);
            return add.toString();
        }

        //减法
        public String subtr(String aVal, String bVal) {
            bd = new BigDecimal(aVal);
            bd1 = new BigDecimal(bVal);
            BigDecimal sub = bd.subtract(bd1);
            return sub.toString();
        }

        //乘法
        public String mult(String aVal, String bVal) {
            bd = new BigDecimal(aVal);
            bd1 = new BigDecimal(bVal);
            BigDecimal sub = bd.multiply(bd1);
            return sub.toString();
        }

        //除法
        public String divdUp(String aVal, String bVal, int num) {
            bd = new BigDecimal(aVal);
            bd1 = new BigDecimal(bVal);
            //保留精度向上进一位
            BigDecimal diviDeup = bd.divide(bd1, num, BigDecimal.ROUND_UP);
            return diviDeup.toString();
        }

        //除法
        public String divideDown(String aVal, String bVal, int num) {
            bd = new BigDecimal(aVal);
            bd1 = new BigDecimal(bVal);
            //保留精度直接舍弃
            BigDecimal divideDown = bd.divide(bd1, num, BigDecimal.ROUND_DOWN);
            return divideDown.toString();
        }

        //除法
        public String divideHup(String aVal, String bVal, int num) {
            bd = new BigDecimal(aVal);
            bd1 = new BigDecimal(bVal);
            //保留精度四舍五入
            BigDecimal divideHup = bd.divide(bd1, num, BigDecimal.ROUND_HALF_UP);
            return divideHup.toString();
        }
    }

    //数字规范 0.01  #.#%
    public static String decimal(String str, String rule) {
        DecimalFormat df = new DecimalFormat(rule);
        String format = df.format(str);
        return format;
    }

    //数字排序冒泡排序
    public static int[] bubbilng(int[] i) {
        for (int a = 0; a < i.length; a++) {
            for (int j = 0; j < i.length - a - 1; j++) {
                if (i[j] > i[j + 1]) {
                    int b = 0;
                    b = i[j + 1];
                    i[j + 1] = i[j];
                    i[j] = b;
                }
            }
        }
        return i;
    }

    //选择排序
    public static int[] chose(int[] i) {
        for (int a = 0; a < i.length; a++) {
            for (int j = a; j < i.length - a; j++) {
                if (i[a] > i[j]) {
                    int b = 0;
                    b = i[a];
                    i[a] = i[j];
                    i[j] = b;
                }
            }
        }
        return i;
    }

    //二分法  必须是排好序的
    public static String method(int[] nums, int ss) {
        boolean bool = true;
        String str;
        int q = 0;
        int w = (nums.length - 1);
        while (q <= w) {
            int svg = (w + q) / 2;
            if (nums[svg] == ss) {
                str = "已经找到了";
                System.out.println("已经找到了" + svg);
                bool = false;
                break;
            } else if (nums[svg] < ss) {
                q = svg + 1;
            } else if (nums[svg] > ss) {
                w = svg - 1;
            }
        }
        if (bool == true) {
            str = "没找到";
            System.out.println("没找到");
        } else {
            str = "找到啦";
            System.out.println("找到啦");
        }
        return str;
    }

    /**
     * 将对象转换为
     *
     * @param type
     * @param lists
     * @param <T>
     * @return
     */
    public static <T> List<T> copyList(Class<T> type, List<?> lists) {
        List<T> dtos = new ArrayList<>();
        for (Object obj : lists) {
            T t = null;
            try {
                t = type.getDeclaredConstructor().newInstance();
            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException | NoSuchMethodException | SecurityException e) {
                e.printStackTrace();
            }
            BeanUtils.copyProperties(obj, t);
            dtos.add(t);
        }
        return dtos;
    }
    //new JSONObject().toJSONString();将对象|字符串转换成json字符串
    // ServletRequestAttributes rb = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    //获取作用域

    /**
     * 过滤空(null)字符串
     *
     * @param str 字符串
     * @return
     */
    public static String toString(Object str) {
        return str == null ? "" : String.valueOf(str).trim();
    }

    /**
     * 格式化 分页请求参数
     *
     * @param limit 每页条数
     * @param page  起始页码 默认0才对
     * @return
     */
    public static Map<String, Object> makeMap(Integer limit, Integer page) {
        Map<String, Object> params = new HashMap<>();
        params.put("page", page);
        params.put("limit", limit);
        if (page > 0) {
            int temp = page;
            page = temp * limit;
            limit = (temp + 1) * limit;
            params.put("page", page);
            params.put("limit", limit);
        }
        return params;
    }

    /**
     * List<Map<String,Object>> 去重
     *
     * @param oldList 列表
     * @param theKey  去重关键字
     * @return
     */
    public static List<Map<String, Object>> listDuplicateRemoval(List<Map<String, Object>> oldList, String theKey) {
        List<Map<String, Object>> newList = new ArrayList<>();
        for (int i = 0; i < oldList.size(); i++) {
            Map<String, Object> oldMap = oldList.get(i);
            if (newList.size() > 0) {
                boolean isContain = false;
                for (int j = 0; j < newList.size(); j++) {
                    Map<String, Object> newMap = newList.get(j);
                    if (newMap.get(theKey).equals(oldMap.get(theKey))) {
                        for (String key : oldMap.keySet()) {
                            newMap.put(key, oldMap.get(key));
                        }
                        isContain = true;
                        break;
                    }
                }
                if (!isContain) {
                    newList.add(oldMap);
                }
            } else {
                newList.add(oldMap);
            }
        }
        return newList;
    }

    /**
     * 获取url 的完整物理路径 用于后台读取文件
     *
     * @param url 传入路径
     * @return 完整物理路径
     */
    public static String getCompletePhysicalPath(String rootPath, String url) {
        System.out.println("rootPath==" + rootPath + "===" + url);
        if (url != null && !url.equals("") && !url.equals("null")) {
            return rootPath + url.replace("/files/", "");
        }
        return "";
    }

    /**
     * String getServerName()：获取服务器名，localhost；
     * String getServerPort()：获取服务器端口号，8080；
     * String getContextPath()：获取项目名，/Example；
     * String getServletPath()：获取Servlet路径，/AServlet；
     * String getQueryString()：获取参数部分，即问号后面的部分：username=zhangsan
     * String getRequestURI()：获取请求URI，等于项目名+Servlet路径：/Example/AServlet
     * String getRequestURL()：获取请求URL，等于不包含参数的整个请求路径：http://localhost:8080/Example/AServlet
     * String request.getRemoteAddr()：获取服务器的IP，如localhost对应ip为127.0.0.1
     *
     * @param imageUrls
     * @param request
     * @return
     */
    // 获取服务器图片完整路径[非物理路径]
    public static String getCompleteUrl(String imageUrls, HttpServletRequest request) {
        String base = ("https://" + request.getServerName() + ":" + request.getServerPort()) + request.getContextPath();
        if (80 == request.getServerPort()) {
            base = ("https://" + request.getServerName()) + request.getContextPath();
        }
        // 图片完整路径
        String image_url = "";
        if (imageUrls != null && imageUrls.contains(",")) {
            String[] images = imageUrls.split(",");
            for (String m : images) {
                if (m.contains("http")) {
                    image_url = image_url + "," + m;
                } else {
                    image_url = image_url + "," + base + m;
                }
            }
            return image_url.substring(1);
        } else if (StringUtils.isNotBlank(imageUrls)) {
            if (imageUrls.contains("http")) {
                return imageUrls;
            }
            return base + imageUrls;
        } else {
            return imageUrls;
        }
    }

    /**
     * 删除服务器上无用的文件
     *
     * @param rootPath
     * @param filePath
     */
    public static void delFile(final String rootPath, final String filePath) {
        try {
            new Thread(() -> {
                String allPath = getCompletePhysicalPath(rootPath, filePath);
                File file = new File(allPath);
                if (file.exists()) {
                    file.delete();
                }
            }).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 对字符串中的字符进行排序，然后返回排好的字符串
     *
     * @param s 乱序字符串
     * @return 排序好的升序字符串
     */
    public static String sortString(String s) {
        String str = s.toUpperCase(); // 小写转大写
        char[] chs = str.toCharArray(); // 转数组
        Arrays.sort(chs); // 排序
        return new String(chs); // 转String
    }
    /**
     * byte[]对象转为字节数组
     * @param obj
     * @return bytes
     * @throws Exception
     */
    public static byte[] object2Bytes(Object obj) throws IOException {
        ByteArrayOutputStream bo=new ByteArrayOutputStream();
        ObjectOutputStream oo=new ObjectOutputStream(bo);
        oo.writeObject(obj);
        byte[] bytes=bo.toByteArray();
        bo.close();
        oo.close();
        return bytes;
    }
    /**
     * byte[]字节数组转对象
     * @param bytes
     * @return Object
     * @throws Exception
     */
    public static Object bytes2Object(byte[] bytes) throws Exception{
        ByteArrayInputStream in=new ByteArrayInputStream(bytes);
        ObjectInputStream sIn=new ObjectInputStream(in);
        return sIn.readObject();
    }
}